import initServerInstance from '../server/initServerInstance';
import { LIMIT_TYPE, LIMITERS } from '../server/plugins/billing/constants';

export function modifyField({ key, field, prev }) {
	let { total = 0, period, unit } = field.toObject({
		getters: false,
		virtuals: false,
	});
	if (total === 0 && prev.value > 0) {
		total = prev.value;
	}
	const used = total - (prev.value || 0);
	field.total = total;
	field.limitType = LIMITERS[key].limitType || field.limitType;
	switch (field.limitType) {
		case LIMIT_TYPE.limit:
			field.used = used;
			delete field.value;
			break;
		case LIMIT_TYPE.period:
			field.time = `${period}${unit}`;
			break;
		case LIMIT_TYPE.duration:
		case LIMIT_TYPE.frequency:
			field.time = `1${unit || 'm'}`;
	}
	delete field.period;
	delete field.unit;

	if (field.charges) {
		field.charges.forEach((c, i) => {
			modifyField({ key, field: c, prev: prev.charges[i].toObject() });
		});
	}
}

export async function addCountEnable({ balance, model }) {
	balance.balance.domain.used = await model.Job.count({
		uid: balance.uid,
	});
	balance.balance.domainEnable.used = await model.Job.count({
		uid: balance.uid,
		enableMonitor: true,
		'verification.isVerified': true,
	});
	balance.balance.httpMaxTask.used =
		(
			await model.Job.aggregate([
				{
					$group: { _id: 'http', count: { $sum: { $size: '$httpSettings' } } },
				},
			])
		).count || 0;
	balance.balance.httpMaxTask.used =
		(
			await model.Job.aggregate([
				{
					$group: { _id: 'ping', count: { $sum: { $size: '$pingSettings' } } },
				},
			])
		).count || 0;
	balance.balance.httpMaxTaskEnable.used =
		(
			await model.Job.aggregate([
				{ $unwind: '$httpSettings' },
				{ $match: { 'httpSettings.enable': true } },
				{
					$group: { _id: 'httpEnable', count: { $sum: 1 } },
				},
			])
		).count || 0;
	balance.balance.pingMaxTaskEnable.used =
		(
			await model.Job.aggregate([
				{ $unwind: '$pingSettings' },
				{ $match: { 'pingSettings.enable': true } },
				{
					$group: { _id: 'pingEnable', count: { $sum: 1 } },
				},
			])
		).count || 0;
	balance.balance.sitePortrait.used =
		(
			await model.Job.aggregate([
				{ $match: { 'vulSettings.enableSitePortraitTriggerMonitor': true } },
				{
					$group: {
						_id: 'enableSitePortraitTriggerMonitor',
						count: { $sum: 1 },
					},
				},
			])
		).count || 0;
}

if (require.main === module) {
	(async () => {
		const server = await initServerInstance({
			loggerConfig: {
				name: 'upgrade',
				alwaysCreate: true,
			},
		});
		const {
			app: { model },
		} = server;
		const { Balance, Plan, AdditionPackage } = model;

		for await (const plan of Plan.find()) {
			plan.limit.domainEnable = plan.limit.domain;
			plan.limit.httpMaxTaskEnable = plan.limit.httpMaxTask;
			plan.limit.pingMaxTaskEnable = plan.limit.pingMaxTask;
			const prev = plan._doc.limit;
			Object.keys(plan.limit.toObject()).forEach(key => {
				const field = plan.limit[key];
				modifyField({ key, field, prev: prev[key] });
			});
			await plan.save();
		}

		for await (const pkg of AdditionPackage.find()) {
			pkg.package.domainEnable = pkg.package.domain;
			pkg.package.httpMaxTaskEnable = pkg.package.httpMaxTask;
			pkg.package.pingMaxTaskEnable = pkg.package.pingMaxTask;
			const prev = pkg._doc.package;
			Object.keys(pkg.package.toObject()).forEach(key => {
				const field = pkg.package[key];
				modifyField({ key, field, prev: prev[key] });
			});
			await pkg.save();
		}

		for await (const balance of Balance.find()) {
			balance.balance.domainEnable = balance.balance.domain;
			balance.balance.httpMaxTaskEnable = balance.balance.httpMaxTask;
			balance.balance.pingMaxTaskEnable = balance.balance.pingMaxTask;
			const prev = balance._doc.balance;
			Object.keys(balance.balance.toObject()).forEach(key => {
				const field = balance.balance[key];
				modifyField({ key, field, prev: prev[key] });
			});
			await addCountEnable({ balance, model });
			await balance.save();
		}

		process.exit();
	})();
}
